package com.zj.esproxy.wrapper;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.zj.esproxy.enums.AggTypeEnum;
import lombok.Data;
import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author arthur_zhou
 * @date 2023/11/7 14:17
 */
@Data
public class AggWrapper {

    private String field;

    @JSONField(name = "agg_type")
    private AggTypeEnum aggType;

    private Integer size;

    private List<AggWrapper> aggs;

    @JSONField(name = "sort_by_key")
    private Boolean sortByKey;

    @JSONField(name = "sort_by_count")
    private Boolean sortByCount;

    private List<String> include;

    private List<Range> ranges;

    @JSONField(serialize = false)
    private final AggNestWrapper aggNestWrapper = new AggNestWrapper(this);

    @Getter
    public static class Range {
        private final Object from;
        private final Object to;

        public Range(Object from, Object to) {
            this.from = from;
            this.to = to;
        }
    }

    public AggWrapper() {
    }

    public AggWrapper(AggWrapper wrapper) {
        if (Objects.isNull(wrapper)) {
            return;
        }
        this.field = wrapper.field;
        this.aggType = wrapper.aggType;
        this.size = wrapper.size;
        if (CollectionUtil.isNotEmpty(wrapper.aggs)) {
            this.aggs = wrapper.aggs;
        }
        this.sortByKey = wrapper.sortByKey;
        this.sortByCount = wrapper.sortByCount;
        if (CollectionUtil.isNotEmpty(wrapper.aggs)) {
            this.include = wrapper.include;
        }
        if (CollectionUtil.isNotEmpty(wrapper.aggs)) {
            this.ranges = wrapper.ranges;
        }
    }

    /**
     * 分组统计
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper normal(String field) {
        return normal(field, null);
    }

    /**
     * 分组统计
     *
     * @param field 聚合字段
     * @param size  返回条数
     * @return 嵌套聚合
     */
    public AggNestWrapper normal(String field, Integer size) {
        return normal(field, size, null, null, (List<String>) null);
    }

    /**
     * 分组统计
     *
     * @param field 聚合字段
     * @param size  返回条数
     * @return 嵌套聚合
     */
    public AggNestWrapper normal(String field, Integer size, Boolean sortByKey, Boolean sortByCount, String... include) {
        return normal(field, size, sortByKey, sortByCount, Objects.nonNull(include) ? Arrays.asList(include) : null);
    }

    /**
     * 分组统计
     *
     * @param field 聚合字段
     * @param size  返回条数
     * @return 嵌套聚合
     */
    public AggNestWrapper normal(String field, Integer size, Boolean sortByKey, Boolean sortByCount, List<String> include) {
        this.field = field;
        this.size = size;
        this.aggType = AggTypeEnum.normal;
        this.sortByKey = sortByKey;
        this.sortByCount = sortByCount;
        this.include = include;
        return this.aggNestWrapper;
    }

    /**
     * 平均
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper avg(String field) {
        this.field = field;
        this.aggType = AggTypeEnum.avg;
        return this.aggNestWrapper;
    }

    /**
     * 最小
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper min(String field) {
        this.field = field;
        this.aggType = AggTypeEnum.min;
        return this.aggNestWrapper;
    }

    /**
     * 最大
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper max(String field) {
        this.field = field;
        this.aggType = AggTypeEnum.max;
        return this.aggNestWrapper;
    }

    /**
     * 求和
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper sum(String field) {
        this.field = field;
        this.aggType = AggTypeEnum.sum;
        return this.aggNestWrapper;
    }


    /**
     * 去重
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper cardinality(String field) {
        this.field = field;
        this.aggType = AggTypeEnum.cardinality;
        return this.aggNestWrapper;
    }

    /**
     * 范围
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper range(String field, List<Range> ranges) {
        this.field = field;
        this.ranges = ranges;
        this.aggType = AggTypeEnum.range;
        return this.aggNestWrapper;
    }

    /**
     * 范围
     *
     * @param field 聚合字段
     * @return 嵌套聚合
     */
    public AggNestWrapper range(String field, Integer size, List<Range> ranges) {
        this.field = field;
        this.size = size;
        this.ranges = ranges;
        this.aggType = AggTypeEnum.range;
        return this.aggNestWrapper;
    }


}
